import {
  getAccessToken,
  getRefershToken,
  removeAccessToken,
  removeRefershToken,
  setAccessToken,
  setRefershToken
} from '@/api'

import axios from 'axios'

const PASS = 'Pass' // header头部 携带长token
// 创建一个axios实例，并设置基本URL
const $axios = axios.create({
  baseURL: import.meta.env.VITE_API_URL
})

let subscribes: any[] = []
let flag = false // 设置开关，保证一次只能请求一次短token，防止客户多次操作，多次请求

/*把过期请求添加在数组中*/
const addRequest = (request: any) => {
  subscribes.push(request)
}

/*调用过期请求*/
const retryRequest = () => {
  console.log('重新请求上次中断的数据', subscribes)
  subscribes.forEach((callback) => {
    callback()
  })
  subscribes = []
}

/*短token过期，携带token去重新请求token*/
export const refreshToken = () => {
  flag = false
  if (!flag) {
    flag = true
    const r_tk = getRefershToken() // 获取长token
    if (r_tk) {
      $axios
        .post(
          '/users/refresh',
          {},
          {
            headers: {
              [PASS]: r_tk
            }
          }
        )
        .then((res) => {
          console.log('获取短token', res)
          //长token失效，退出登录 //这个功能没做
          if (res.code == 4006) {
            subscribes = []
            console.log('长token失效,重新登录')
            flag = false
            removeRefershToken()
            removeAccessToken()
            window.location.href = '/login'
          } else if (res.code === 200) {
            // 存储新的token
            console.log('新的accessToken,,,新的refreshToken')
            setAccessToken(res.accessToken)
            setRefershToken(res.refreshToken)
            flag = false
            // 重新请求数据
            retryRequest()
            return
          }
        })
        .catch((err) => {
          console.log(err)
        })
    }
  }
}

// 添加请求拦截器
$axios.interceptors.request.use(
  function (config) {
    const AUTH = 'Authorization' // header头部 携带短token
    config.headers[AUTH] = getAccessToken()
    // config.headers[PASS] = getRefershToken()
    return config // 返回配置对象
  },
  function (error) {
    // 处理请求错误
    return Promise.reject(error) // 抛出错误
  }
)

// 添加响应拦截器
$axios.interceptors.response.use(
  (response) => {
    // 获取到配置和后端响应的数据
    const { config, data } = response
    return new Promise((resolve) => {
      // 短token失效
      if (data.code === 4003) {
        // 移除失效的短token
        removeAccessToken()
        // 把过期请求存储起来，用于请求到新的短token，再次请求，达到无感刷新
        addRequest(() => resolve($axios(config)))
        // 携带长token去请求新的token
        refreshToken()
      } else if (data.code === 4001) {
        window.location.href = '/login'
      } else {
        // 有效返回相应的数据
        let newData: object = []
        if (data.data) {
          newData = data.data
        } else {
          newData = data
        }
        resolve(newData)
      }
    }).catch((err) => {
      console.log(err)
    })
  },
  (error) => {
    return Promise.reject(error)
  }
)

export default $axios // 导出axios实例
